// JavaScript source code
//
// @Author: zhengqi Wu
// @Description:
// @Version: 1.0.0
// @Date: 2021/3/29 11:01 ????
// @Copyright: MIN-Group??????????????????????��???????????????????????????��??????????????
//

const {SelfEncodingBase} = require("../encoding");
const {TlvComponentBase, InitialAble} = require("./TlvComponentBase");
const {ComponentType} = require("../encoding/TLV");
const {ControlParameterMtu} = require("../component/ControlParameterMtu");
const {ControlParameterUriScheme} = require("../component/ControlParameterUriScheme");
const {ControlParameterLogicFacePersistency} = require("../component/ControlParameterLogicFacePersistency");
const {ControlParameterLocalUri} = require("../component/ControlParameterLocalUri");
const {ControlParameterUri} = require("../component/ControlParameterUri");
const {ControlParameterExpireTime} = require("../component/ControlParameterExpireTime");
const {ControlParameterCount} = require("../component/ControlParameterCount");
const {ControlParameterCapacity} = require("../component/ControlParameterCapacity");
const {ControlParameterCost} = require("../component/ControlParameterCost");
const {ControlParameterLogicFaceId} = require("../component/ControlParameterLogicFaceId");
const {ControlParameterPrefix} = require("../component/ControlParameterPrefix");
var aggregation = require('../common/aggregation')

class ControlParameters extends aggregation(TlvComponentBase,InitialAble,SelfEncodingBase){
    constructor() {
        super()
        this.ControlParameterPrefix = new ControlParameterPrefix() // 前缀标识
        this.ControlParameterLogicFaceId = new ControlParameterLogicFaceId() // 逻辑faceId
        this.ControlParameterCost = new ControlParameterCost() // 链路代价
        this.ControlParameterCapacity = new ControlParameterCapacity() // CS 容量
        this.ControlParameterCount = new ControlParameterCount() // 需要删除的cs表项数
        this.ControlParameterExpireTime = new ControlParameterExpireTime() // 超时时间
        this.ControlParameterUri = new ControlParameterUri() // 远端地址
        this.ControlParameterLocalUri = new ControlParameterLocalUri() // 本地地址
        this.ControlParameterLogicFacePersistency = new ControlParameterLogicFacePersistency() // 逻辑接口持久性
        this.ControlParameterUriScheme = new ControlParameterUriScheme() // 逻辑地址模式
        this.ControlParameterMtu = new ControlParameterMtu() // MTU
        this.ControlParameterPasswd = new ControlParameterPasswd() // 密码
        this.ControlParameterCommonString = new ControlParameterCommonString() // 通用字符串参数
    }

    /**
     * ��ControlParameter������ֽ�����
     * @param enc {Encoder}
     * @returns totalLength {Number}
     */
    wireEncode(enc){
        let totalLength = 0
        try{
            // ���� TLV-VALUE
            // 1. ControlParameterPrefix
            if (this.ControlParameterPrefix.isInitial()){
                // ����ʱ�׳��쳣
                let tmpLen = this.ControlParameterPrefix.wireEncode(enc)
                totalLength += tmpLen
            }

            // 2. ControlParameterLogicFaceId
            if (this.ControlParameterLogicFaceId.isInitial()){
                // ����ʱ�׳��쳣
                let tmpLen = this.ControlParameterLogicFaceId.wireEncode(enc)
                totalLength += tmpLen
            }

            // 3. ControlParameterCost
            if (this.ControlParameterCost.isInitial()){
                // ����ʱ�׳��쳣
                let tmpLen = this.ControlParameterCost.wireEncode(enc)
                totalLength += tmpLen
            }

            // 4. ControlParameterCapacity
            if (this.ControlParameterCapacity.isInitial()){
                // ����ʱ�׳��쳣
                let tmpLen = this.ControlParameterCapacity.wireEncode(enc)
                totalLength += tmpLen
            }

            // 5. ControlParameterCount
            if (this.ControlParameterCount.isInitial()){
                // ����ʱ�׳��쳣
                let tmpLen = this.ControlParameterCount.wireEncode(enc)
                totalLength += tmpLen
            }

            // 6. ControlParameterExpireTime
            if (this.ControlParameterExpireTime.isInitial()){
                // ����ʱ�׳��쳣
                let tmpLen = this.ControlParameterExpireTime.wireEncode(enc)
                totalLength += tmpLen
            }

            // 7. ControlParameterUri
            if (this.ControlParameterUri.isInitial()){
                // ����ʱ�׳��쳣
                let tmpLen = this.ControlParameterUri.wireEncode(enc)
                totalLength += tmpLen
            }

            // 8. ControlParameterLocalUri
            if (this.ControlParameterLocalUri.isInitial()){
                // ����ʱ�׳��쳣
                let tmpLen = this.ControlParameterLocalUri.wireEncode(enc)
                totalLength += tmpLen
            }

            // 9. ControlParameterLogicFacePersistency
            if (this.ControlParameterLogicFacePersistency.isInitial()){
                // ����ʱ�׳��쳣
                let tmpLen = this.ControlParameterLogicFacePersistency.wireEncode(enc)
                totalLength += tmpLen
            }

            // 10. ControlParameterUriScheme
            if (this.ControlParameterUriScheme.isInitial()){
                // ����ʱ�׳��쳣
                let tmpLen = this.ControlParameterUriScheme.wireEncode(enc)
                totalLength += tmpLen
            }

            // 11. ControlParameterMtu
            if (this.ControlParameterMtu.isInitial()){
                // ����ʱ�׳��쳣
                let tmpLen = this.ControlParameterMtu.wireEncode(enc)
                totalLength += tmpLen
            }

            // 12. ControlParameterPasswd
            if (this.ControlParameterPasswd.isInitial()){
                let tmpLen = this.ControlParameterPasswd.wireEncode(enc)
                totalLength += tmpLen
            }

            // 13. ControlParameterCommonString
            if (this.ControlParameterCommonString.isInitial()){
                let tmpLen = this.ControlParameterCommonString.wireEncode(enc)
                totalLength += tmpLen
            }

            // ���� TLV-LENGTH
            let tmpLen = enc.prependVarNumber(BigInt(totalLength))
            totalLength += tmpLen

            // ���� TLV-TYPE
            tmpLen = enc.prependVarNumber(ComponentType.TlvManagementControlParameters)
            totalLength += tmpLen
        }catch (e){
            throw e
        }
        return totalLength
    }

    /**
     * �� TLV Block �н����һ�� ControlParameters
     * @param block {Block}
     */
    wireDecode(block){
        try{
            // 1. ������Block
            block.parseSubElements()

            // 2. ��������
            let elements = block.getSubElements()
            for(let i = 0; i < elements.length; i++){
                let element = elements[i]
                switch (element.getType()){
                    case ComponentType.TlvManagementPrefix:
                        this.ControlParameterPrefix.wireDecode(element)
                        break
                    case ComponentType.TlvManagementLogicFaceId:
                        this.ControlParameterLogicFaceId.wireDecode(element)
                        break
                    case ComponentType.TlvManagementCost:
                        this.ControlParameterCost.wireDecode(element)
                        break
                    case ComponentType.TlvManagementCapacity:
                        this.ControlParameterCapacity.wireDecode(element)
                        break
                    case ComponentType.TlvManagementCount:
                        this.ControlParameterCount.wireDecode(element)
                        break
                    case ComponentType.TlvManagementExpireTime:
                        this.ControlParameterExpireTime.wireDecode(element)
                        break
                    case ComponentType.TlvManagementUri:
                        this.ControlParameterUri.wireDecode(element)
                        break
                    case ComponentType.TlvManagementLocalUri:
                        this.ControlParameterLocalUri.wireDecode(element)
                        break
                    case ComponentType.TlvManagementLogicFacePersistency:
                        this.ControlParameterLogicFacePersistency.wireDecode(element)
                        break
                    case ComponentType.TlvManagementUriScheme:
                        this.ControlParameterUriScheme.wireDecode(element)
                        break
                    case ComponentType.TlvManagementMtu:
                        this.ControlParameterMtu.wireDecode(element)
                        break
                    case ComponentType.TlvManagementPasswd:
                        this.ControlParameterPasswd.wireDecode(element)
                        break
                    case ComponentType.TlvManagementCommonString:
                        this.TlvManagementCommonString.wireDecode(element)
                        break
                }
            }
        }catch (e){
            // 3. �׳��쳣
            throw e
        }
    }
}
module.exports = {ControlParameters: ControlParameters}
